package edu.nf.supermarket.web.controller.app;


import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import edu.nf.supermarket.base.BaseController;
import edu.nf.supermarket.consts.AlipayConfigEnum;
import edu.nf.supermarket.consts.PayStatusEnum;
import edu.nf.supermarket.entity.Orders;
import edu.nf.supermarket.exception.PayException;
import edu.nf.supermarket.result.ResultVO;
import edu.nf.supermarket.service.CouponService;
import edu.nf.supermarket.service.OrderService;
import edu.nf.supermarket.service.pay.AlipayService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author yjj
 * @date 2025-05-21
 */
@RestController
@RequestMapping("/alipay")
public class AlipayController extends BaseController {
    @Autowired
    private AlipayService alipayService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CouponService couponService;

    /**
     * 创建订单并返回支付二维码（使用之前要打开cpolar获取公网地址， 并修改枚举类和支付宝沙箱后台的回调地址）
     *
     * @param orderNo 订单编号
     * @param amount  金额
     * @return 结果集
     */
    @PostMapping("/qrcode")
    public ResultVO<String> pay(@RequestParam("orderNo") String orderNo,
                                @RequestParam("amount") String amount,
                                @RequestParam(name = "couponId", defaultValue = "0") Integer couponId,
                                @RequestParam("userId") Integer userId) {
        String order = null;
        try {
            Map<String, Object> extraParams = new HashMap<>();

            String expireTime = LocalDateTime.now()
                    .plusMinutes(3)
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            Orders orderByOrderID = orderService.findOrderByOrderID(orderNo);
            String subject = generateSubject(orderByOrderID);


            extraParams.put("timeExpire", expireTime);
            extraParams.put("passback_params ", "couponId=" + couponId + "&userId=" + userId);
            order = alipayService.createWebOrder(orderNo, amount, subject, extraParams);
        } catch (Exception e) {
            throw new PayException(1006, "支付宝支付失败");
        }
        return success(order);
    }

    public String generateSubject(Orders order) {
        StringBuilder subject = new StringBuilder();
        if (Objects.nonNull(order.getCommodityList())) {
            order.getCommodityList().forEach(commodity -> {
                subject.append(commodity.getCommodityName())
                        .append(" x ").append(commodity.getCommodityNum())
                        .append("\t")
                        .append(commodity.getCommoditySalePrice())
                        .append("\n");
            });
        }
        return subject.toString();
    }

    /**
     * 接收支付宝返回的用户支付结果
     *
     * @param params 支付宝返回的参数
     * @return
     */
    @PostMapping(path = "/notify")
    public String handleAliPayNotify(@RequestParam Map<String, String> params) {
        System.out.println("收到异步通知" + params);
        try {
            // 1. 验签
            if (AlipaySignature.rsaCheckV1(params, AlipayConfigEnum.getInstance().getAlipayPublicKey(), "UTF-8", "RSA2")) {
                // 2. 校验通知类型和交易状态
                String tradeStatus = params.get("trade_status");
                if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    // 3. 更新订单状态
                    String outTradeNo = params.get("out_trade_no");//获取订单号
                    String gmtPaymentStr = params.get("gmt_payment");//获取用户支付时间
                    String passbackParams = params.get("passback_params");//获取优惠卷Id
                    String payAmount = params.get("total_amount");
                    if (passbackParams != null) {
                        Map<String, String> paramMap = new HashMap<>();
                        for (String param : passbackParams.split("&")) {
                            String[] pair = param.split("=");
                            if (pair.length == 2) {
                                paramMap.put(pair[0], pair[1]);
                            }
                        }
                        if (!Objects.equals(paramMap.get("couponId"), "0")) {
                            couponService.updateCouponStatus(Integer.parseInt(paramMap.get("couponId")), Integer.parseInt(paramMap.get("userId")), (byte) 1);
                        }
                    }

                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime payTime = LocalDateTime.parse(gmtPaymentStr, formatter);
                    System.out.println("订单 " + outTradeNo + " 支付成功");
                    orderService.updateOrderStatus(outTradeNo, (byte) 1);
                    orderService.addPayTime(payTime, outTradeNo);
                    orderService.addOrderAmount(outTradeNo, new BigDecimal(payAmount));
                }
                return "success"; // 必须返回 success
            } else {
                return "fail";
            }
        } catch (AlipayApiException e) {
            return "fail";
        }
    }

    /**
     * 测试方法（别删）
     *
     * @return
     */
    @GetMapping("/notify")
    public String testNotify() {
        return "GET /notify 接口已收到请求";
    }

    /**
     * 前端确认客户支付状态方法
     *
     * @param orderNO
     * @return
     */
    @GetMapping("/status")
    public ResultVO<String> status(@RequestParam("orderNO") String orderNO) {
        Orders orderByOrderID = orderService.findOrderByOrderID(orderNO);
        //判断是否支付成功
        boolean paid = PayStatusEnum.isPaid(orderByOrderID.getStatus());
        return success(paid ? "已支付" : "未支付");
    }

    /**
     * 支付宝支付完成后，用户点击【返回商户页面】时跳转的接口
     *
     * @return 跳转到支付结果页面
     */
    @GetMapping("/return")
    public void alipayReturn(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 获取支付宝GET请求的参数（需验签，此处省略）
        Map<String, String> params = new HashMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String name = parameterNames.nextElement();
            params.put(name, request.getParameter(name));
        }

        // 2. 验证签名（实际项目必须做！）
        // boolean signVerified = AlipaySignature.rsaCheckV1(...);
        // if (!signVerified) { ... }

        // 3. 构造前端URL（携带订单号等参数）
        String frontendUrl = "https://a3d0e68.r31.cpolar.top" +
                "?out_trade_no=" + params.get("out_trade_no") +
                "&trade_status=" + params.get("trade_status");

        // 4. 重定向到前端页面
        response.sendRedirect(frontendUrl);
    }

}
